Skip to content

Conversation

@jeromemarchand
Copy link
Contributor

Since kernel 6.10, PAGE_OFFSET on s390 is not a constant anymore but points to vm.identity_base and needs to be dereferenced properly with bpf_probe_read_kernel().

Fixes the following error:
bpf: Failed to load program: Permission denied
0: R1=ctx() R10=fp0
; int trace_0(struct pt_regs *ctx) { @ main.c:172
0: (bf) r6 = r1 ; R1=ctx() R6_w=ctx()
; u64 tgid_pid = bpf_get_current_pid_tgid(); @ main.c:68
1: (85) call bpf_get_current_pid_tgid#14 ; R0_w=scalar()
2: (7b) *(u64 *)(r10 -8) = r0 ; R0_w=scalar(id=1) R10=fp0 fp-8_w=scalar(id=1)
3: (b7) r7 = 0 ; R7_w=0
; struct entry_t entry = {}; @ main.c:75
4: (7b) *(u64 *)(r10 -16) = r7 ; R7_w=0 R10=fp0 fp-16_w=0
5: (7b) *(u64 *)(r10 -24) = r7 ; R7_w=0 R10=fp0 fp-24_w=0
; entry.start_ns = bpf_ktime_get_ns(); @ main.c:76
6: (85) call bpf_ktime_get_ns#5 ; R0=scalar()
7: (7b) *(u64 *)(r10 -32) = r0 ; R0=scalar(id=2) R10=fp0 fp-32_w=scalar(id=2)
; entry.id = id; @ main.c:77
8: (7b) *(u64 *)(r10 -40) = r7 ; R7=0 R10=fp0 fp-40_w=0
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
9: (18) r2 = 0xfd038000 ; R2_w=map_ptr(map=stacks,ks=4,vs=1016)
; return bcc_get_stackid_(ctx, (void *)map, flags); @ helpers.h:660
11: (bf) r1 = r6 ; R1_w=ctx() R6=ctx()
12: (b7) r3 = 0 ; R3_w=0
13: (85) call bpf_get_stackid#27 ; R0_w=scalar()
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
14: (63) *(u32 *)(r10 -24) = r0 ; R0_w=scalar() R10=fp0 fp-24=mmmmscalar()
; if (entry.kernel_stack_id >= 0) { @ main.c:96
15: (6d) if r7 s> r0 goto pc+6 ; R0_w=scalar(smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff)) R7=0
; u64 ip = PT_REGS_IP(ctx); @ main.c:97
16: (79) r1 = *(u64 *)(r6 +16) ; R1_w=scalar() R6=ctx()
; page_offset = PAGE_OFFSET; @ main.c:114
17: (18) r2 = 0x0 ; R2_w=0
19: (79) r2 = *(u64 *)(r2 +16)
R2 invalid mem access 'scalar'
processed 18 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1

Traceback (most recent call last):
File "/usr/share/bcc/tools/funcslower", line 266, in
b.attach_kprobe(event=function, fn_name="trace_%d" % i)
File "/usr/lib/python3.12/site-packages/bcc/init.py", line 877, in attach_kprobe
fn = self.load_func(fn_name, BPF.KPROBE)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/site-packages/bcc/init.py", line 552, in load_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'trace_0': Permission denied

#else
page_offset = __PAGE_OFFSET_BASE_L4;
#endif
#elif defined(__identity_base)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about #elif defined(CONFIG_S390) && defined(__identity_base) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently __identity_base is only defined on s390 so they're equivalent.
I remember hesitating between the two and my reason to chose the former is that if __identity_base is ever defined on an other arch, it would most likely be for the same purpose.
On the other hand, PAGE_OFFSET seems to be very arch specific and I don't how likely my scenario is likely to happen.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, Thank you.

tools/profile.py Outdated
#endif
#elif defined(__identity_base)
// s390 6.10 and later PAGE_OFFSET is not a constant and need
// to be read from the kernel adress space
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

address, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix.

Since kernel 6.10, PAGE_OFFSET on s390 is not a constant anymore but
points to vm.identity_base and needs to be dereferenced properly with
bpf_probe_read_kernel().

Fixes the following error:
bpf: Failed to load program: Permission denied
0: R1=ctx() R10=fp0
; int trace_0(struct pt_regs *ctx) { @ main.c:172
0: (bf) r6 = r1                       ; R1=ctx() R6_w=ctx()
; u64 tgid_pid = bpf_get_current_pid_tgid(); @ main.c:68
1: (85) call bpf_get_current_pid_tgid#14      ; R0_w=scalar()
2: (7b) *(u64 *)(r10 -8) = r0         ; R0_w=scalar(id=1) R10=fp0 fp-8_w=scalar(id=1)
3: (b7) r7 = 0                        ; R7_w=0
; struct entry_t entry = {}; @ main.c:75
4: (7b) *(u64 *)(r10 -16) = r7        ; R7_w=0 R10=fp0 fp-16_w=0
5: (7b) *(u64 *)(r10 -24) = r7        ; R7_w=0 R10=fp0 fp-24_w=0
; entry.start_ns = bpf_ktime_get_ns(); @ main.c:76
6: (85) call bpf_ktime_get_ns#5       ; R0=scalar()
7: (7b) *(u64 *)(r10 -32) = r0        ; R0=scalar(id=2) R10=fp0 fp-32_w=scalar(id=2)
; entry.id = id; @ main.c:77
8: (7b) *(u64 *)(r10 -40) = r7        ; R7=0 R10=fp0 fp-40_w=0
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
9: (18) r2 = 0xfd038000               ; R2_w=map_ptr(map=stacks,ks=4,vs=1016)
; return bcc_get_stackid_(ctx, (void *)map, flags); @ helpers.h:660
11: (bf) r1 = r6                      ; R1_w=ctx() R6=ctx()
12: (b7) r3 = 0                       ; R3_w=0
13: (85) call bpf_get_stackid#27      ; R0_w=scalar()
; entry.kernel_stack_id = bcc_get_stackid(bpf_pseudo_fd(1, -3), ctx, 0); @ main.c:94
14: (63) *(u32 *)(r10 -24) = r0       ; R0_w=scalar() R10=fp0 fp-24=mmmmscalar()
; if (entry.kernel_stack_id >= 0) { @ main.c:96
15: (6d) if r7 s> r0 goto pc+6        ; R0_w=scalar(smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff)) R7=0
; u64 ip = PT_REGS_IP(ctx); @ main.c:97
16: (79) r1 = *(u64 *)(r6 +16)        ; R1_w=scalar() R6=ctx()
; page_offset = PAGE_OFFSET; @ main.c:114
17: (18) r2 = 0x0                     ; R2_w=0
19: (79) r2 = *(u64 *)(r2 +16)
R2 invalid mem access 'scalar'
processed 18 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1

Traceback (most recent call last):
  File "/usr/share/bcc/tools/funcslower", line 266, in <module>
    b.attach_kprobe(event=function, fn_name="trace_%d" % i)
  File "/usr/lib/python3.12/site-packages/bcc/__init__.py", line 877, in attach_kprobe
    fn = self.load_func(fn_name, BPF.KPROBE)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/bcc/__init__.py", line 552, in load_func
    raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'trace_0': Permission denied

Signed-off-by: Jerome Marchand <[email protected]>
Copy link
Collaborator

@ekyooo ekyooo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.

@ekyooo ekyooo merged commit d8595ee into iovisor:master Jan 18, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants